﻿using System;
using System.Windows;
using WPFMediaKit.DirectShow.Controls;
using WPFMediaKit.DirectShow.MediaPlayers;

namespace MEF_Test.Bricks.Wrappers
{
    public class MydraMediaUriElement : MediaUriElement
    {
        public MydraMediaUriElement()
        {
            this.MediaUriPlayer.MediaPositionChanged += MediaUriPlayer_MediaPositionChanged;
        }

        void MediaUriPlayer_MediaPositionChanged(object sender, EventArgs e)
        {
            var check = Dispatcher.CheckAccess();
            Action action = () =>
                                {
                                    RoutedEvent mediaPositionChangedEvent = MediaPositionChangedEvent;
                                    RaiseEvent(new RoutedEventArgs(mediaPositionChangedEvent));
                                };
            if (!check)
            {
                Dispatcher.Invoke(action);
            }
            else
            {
                action.Invoke();
            }
        }


        /// <summary>
        /// Gets or sets the media position.
        /// </summary>
        /// <value>The media position.</value>
        /// <remarks>
        /// This facade allows us to add logic when the Media Position is manually set, as opposed to the regulas MediaUriElement where this property is called whenever the position changes, independently of the value being set manually or as just the next logical value of a playback. ( seeking vs playback ). Downside is : as it isn't a Dependency property, we cannot animate it nor bind it, but... who cares ?</remarks>
        new public long MediaPosition
        {
            get { return base.MediaPosition; }            
            set
            {
                base.MediaPosition = value;
                OnMediaPositionSeek(this, new MediaPositionSeekEventArgs{NewPosition = value});
            }
        }

        protected void OnMediaPositionSeek(object sender, MediaPositionSeekEventArgs eventArgs)
        {
            if (MediaPositionSeek != null)
            {
                MediaPositionSeek(this, eventArgs);
            }
        }

        public event EventHandler<MediaPositionSeekEventArgs> MediaPositionSeek;

        public event RoutedEventHandler MediaPositionChanged
        {
            add
            {
                AddHandler(MediaPositionChangedEvent, value);
            }
            remove
            {
                RemoveHandler(MediaPositionChangedEvent, value);
            }
        }
        

        /// <summary>
        /// Occurs when the media position is changed.
        /// </summary>
        /// <remarks>This is a facade proxy for the same event on the child object <see cref="MediaUriPlayer"/>.</remarks>
        static public RoutedEvent MediaPositionChangedEvent = EventManager.RegisterRoutedEvent(
        "MediaPositionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MydraMediaUriElement));

        public new MediaUriPlayer MediaUriPlayer 
        {
            get
            {
                return base.MediaUriPlayer;
            }
        }
    }

    public class MediaPositionSeekEventArgs : EventArgs
    {
        public long NewPosition { get; set; }
    }
}
